package com.dding.cms.base.web.util;

import static org.dding.mvc.ActionSupport.FAILURE;
import static org.dding.mvc.ActionSupport.MESSAGE;
import static org.dding.mvc.ActionSupport.STATUS;
import static org.dding.mvc.ActionSupport.SUCCESS;
import static org.dding.mvc.ActionSupport.ajaxJsonMessage;

import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;

import org.dding.core.log.ILogger;
import org.dding.core.log.LoggerFactory;
import org.dding.core.util.StringUtils;
import org.dding.mvc.InvocationContext;

public class PersistenceUtil {

	private static ILogger logger = LoggerFactory
			.getLogger(PersistenceUtil.class);

	// TODO:批量删除
	public static void deleteBo(InvocationContext invocationContext,
			Class<?> clazz, String query) {
		String[] ids = invocationContext.getParameterValues("ids");
		Map<String, String> result = new HashMap<String, String>();
		if (ids.length == 0) {
			result.put(STATUS, FAILURE);
			result.put(MESSAGE, "请选择删除项.");
		}
		for (String id : ids) {
			try {
				if (!StringUtils.isEmpty(id)) {

					Method m = clazz.getMethod("delete", new Class[] {
							String.class, Object[].class });
					m.invoke(clazz, new Object[] { query, new Object[] { id } });
					result.put(STATUS, SUCCESS);
					result.put(MESSAGE, "删除成功.");
				} else {
					result.put(STATUS, FAILURE);
					result.put(MESSAGE, "ID不能为空.");
				}
			} catch (Throwable e) {
				logger.warn(e);
				result.put(STATUS, FAILURE);
				result.put(MESSAGE, "删除失败.");
			}
			ajaxJsonMessage(result, invocationContext);
		}
	}

	// TODO:批量删除
	public static void deleteCascadeBo(InvocationContext invocationContext,
			Object object, String field) {
		deleteCascade(invocationContext, object, field, "deleteCascade", null);
	}

	// TODO:批量删除
	public static <TX> void deleteCascadeBoExcept(
			InvocationContext invocationContext, Object object, String field,
			Class<TX> paramType, TX... params) {
		deleteCascade(invocationContext, object, field, "deleteCascadeExcept",
				paramType, params);
	}

	private static <TX> void deleteCascade(InvocationContext invocationContext,
			Object object, String field, String mehod, Class<TX> paramType,
			TX... params) {
		String[] ids = invocationContext.getParameterValues("ids");
		Map<String, String> result = new HashMap<String, String>();
		if (ids.length == 0) {
			result.put(STATUS, FAILURE);
			result.put(MESSAGE, "请选择删除项.");
		}
		for (String id : ids) {
			try {
				if (!StringUtils.isEmpty(id)) {
					Method setMethod = object.getClass().getMethod("set",
							String.class, Object.class);
					setMethod.invoke(object, field, id);
					Method m;
					if (paramType == null) {
						m = object.getClass().getMethod(mehod);
					} else {
						m = object.getClass().getMethod(mehod, paramType);
					}
					m.invoke(object, params);
					result.put(STATUS, SUCCESS);
					result.put(MESSAGE, "删除成功.");
				} else {
					result.put(STATUS, FAILURE);
					result.put(MESSAGE, "ID不能为空.");
				}
			} catch (Throwable e) {
				logger.warn(e);
				result.put(STATUS, FAILURE);
				result.put(MESSAGE, "删除失败.");
			}
		}
		ajaxJsonMessage(result, invocationContext);
	}

	public static void updateBo(InvocationContext invocationContext,
			Set<String> columns, Class<?> clazz, String key) {
		Map<String, String[]> modelMap = invocationContext.getParameterMap();
		String[] id = modelMap.get(key);
		if (id[0] == null)
			return;
		StringBuilder updates = new StringBuilder();
		List<String> params = new ArrayList<String>(modelMap.size());
		for (Entry<String, String[]> entry : modelMap.entrySet()) {
			if (!columns.contains(entry.getKey()) || key.equals(entry.getKey()))
				continue;
			updates.append(entry.getKey() + "=?");
			updates.append(",");
			params.add(entry.getValue()[0]);
		}
		params.add(id[0]);
		try {
			Method m = clazz.getMethod("update", new Class[] { String.class,
					String.class, Object[].class });
			m.invoke(clazz,
					new Object[] { updates.substring(0, updates.length() - 1),
							key + " = ?", params.toArray() });
		} catch (Exception e) {
			logger.error(e);
		}
	}
}
